﻿using Se.Log;
using Se.Net.Sockets;
using Se.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Se.Model.Generator;
using Se.Protocol;

namespace Se.Model.Host
{
    public class SocketHost
    {
        /// <summary>
        /// Session 集合
        /// </summary>
        public Dictionary<string, SocketSession> SessionSet { get; private set; }

        public SocketListener Listener;

        public ServerReceivedHandler ReceivedHandler;

        public SocketHost(SocketListener listener, IServerReceived controller)
        {
            this.Listener = listener;
            this.SessionSet = new Dictionary<string, SocketSession>();
            this.ReceivedHandler = new ServerReceivedHandler(controller);
            listener.SocketConnected += Listener_SocketConnected;
            listener.SocketReceived += Listener_SocketReceived;
            listener.SocketDisConnected += listener_SocketDisConnected;
        }

        /// <summary>
        /// Connected
        /// </summary>
        /// <param name="socket"></param>
        private void Listener_SocketConnected(ExSocket socket)
        {
            var session = new SocketSession(socket, this, socket.Key);
            this.SessionSet[socket.Key] = session;
        }

        /// <summary>
        /// 接受数据
        /// </summary>
        /// <param name="obj"></param>
        private void Listener_SocketReceived(SocketReceivedArgs receivedData)
        {
            //TODO 接收数据统计，以防止发包工具

            var data = new List<byte>(receivedData.Data);
            while (data.Count > 0)
            {
                var commonMsg = ServerMessage.ParseFrom(data.ToArray());
                data.RemoveRange(0, commonMsg.SerializedSize);
                try
                {
                    this.ReceivedHandler.Handle(this.SessionSet[receivedData.Socket.Key], commonMsg);
                }
                catch (Exception ex)
                {
                    SeLog.Error("SocketHost->Listener_SocketReceived errorinfo {0}", ex.ToString());
                }
            }
        }

        private void listener_SocketDisConnected(ExSocket exSocket)
        {
            SeLog.Warn("断开连接");
        }

        public void Start()
        {
            this.Listener.StartListen();
            SeLog.Warn("服务器开始监听中");
        }
    }
}
